package com.sat.client.utils

import android.content.ContentValues
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
import androidx.annotation.RequiresApi
import com.liulishuo.filedownloader.BaseDownloadTask
import com.liulishuo.filedownloader.FileDownloadListener
import com.liulishuo.filedownloader.FileDownloader
import com.sat.client.app.APP
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.OutputStream

object FileDownloaderHelper {

    init {
        FileDownloader.setup(APP.context)
    }

    fun downloadFile(url: String, fileName: String, onComplete: () -> Unit, onError: (Throwable) -> Unit) {
        val cacheDir = APP.context.cacheDir.absolutePath
        val cacheFilePath = "$cacheDir/$fileName"
        val listener = object : FileDownloadListener() {
            override fun pending(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
            }

            override fun progress(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
                Log.e("file","========================$soFarBytes===$totalBytes")
            }

            override fun completed(task: BaseDownloadTask) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    moveFileToDownloadsQAndAbove(cacheFilePath, fileName)
                } else {
                    // Directly download to the downloads directory for Android versions below Q
                    saveFileToDownloadsPreQ(cacheFilePath, fileName)
                }
                // Delete the cache file after moving
                deleteCacheFile(cacheFilePath)
                // Invoke the completion callback
                onComplete()
            }

            override fun paused(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {}

            override fun error(task: BaseDownloadTask, e: Throwable) {
                e.printStackTrace()
                // Invoke the error callback
                onError(e)
            }

            override fun warn(task: BaseDownloadTask) {}
        }

        FileDownloader.getImpl().create(url)
            .setPath(cacheFilePath)
            .setListener(listener)
            .start()
    }

    @RequiresApi(Build.VERSION_CODES.Q)
    private fun moveFileToDownloadsQAndAbove(cacheFilePath: String, fileName: String) {
        val resolver = APP.context.contentResolver
        val contentValues = ContentValues().apply {
            put(MediaStore.Downloads.DISPLAY_NAME, fileName)
            put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream")
            put(MediaStore.Downloads.IS_PENDING, 1)
        }

        val downloadUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
        downloadUri?.let { uri ->
            val outputStream: OutputStream? = resolver.openOutputStream(uri)
            val inputStream = FileInputStream(File(cacheFilePath))
            outputStream?.use { stream ->
                inputStream.use { input ->
                    input.copyTo(stream)
                }
            }
            contentValues.clear()
            contentValues.put(MediaStore.Downloads.IS_PENDING, 0)
            resolver.update(uri, contentValues, null, null)
        }
    }

    private fun saveFileToDownloadsPreQ(cacheFilePath: String, fileName: String) {
        val downloadsDir =
            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
        val file = File(downloadsDir, fileName)
        try {
            FileInputStream(File(cacheFilePath)).use { input ->
                FileOutputStream(file).use { output ->
                    input.copyTo(output)
                }
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    private fun deleteCacheFile(cacheFilePath: String) {
        val cacheFile = File(cacheFilePath)
        if (cacheFile.exists()) {
            cacheFile.delete()
        }
    }
}
